{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# mnist-fashion\n",
    "\n",
    "\n",
    "## 任务简介\n",
    "\n",
    "数据集包含 58000 张灰度图片，分10个类别，图片尺寸为 28\\*28，要求从 50000 张图片中寻找 10 种服装类别的特征，得到一个图像分类器。并测试 8000 张图片，验证分类器的性能。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import tensorflow.keras as keras\n",
    "\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 读取数据\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [],
   "source": [
    "(X_train, y_train), (X_test, y_test) = keras.datasets.fashion_mnist.load_data()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((48000, 784), (48000,))"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "X_train = X_train.reshape((-1, 28*28))\n",
    "X_test = X_test.reshape((-1, 28*28))\n",
    "\n",
    "X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.2)\n",
    "\n",
    "X_train.shape, y_train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "255"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 观察样本"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x576 with 25 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(5, 5, figsize=(8,8))\n",
    "samples = X_train[0:25]\n",
    "labels = y_train[0:25]\n",
    "\n",
    "for axi, sample, label in zip(ax.flat, samples, labels):\n",
    "    axi.set(xticks=[], yticks=[])\n",
    "    axi.imshow(sample.reshape((28, 28)), interpolation='nearest', cmap=plt.cm.binary)\n",
    "    axi.text(0.05, 0.05, str(label),transform=axi.transAxes, color='blue')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 线性模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 数据预处理\n",
    "\n",
    "首先需要对数据做归一化处理，另外由于数据维度很高（784）可以先对其进行降维。\n",
    "\n",
    "\n",
    "为了在降维的过程中不至于大量损失原始信息，这里要求选取的主成分要能够保留原始数据 95% 的方差。`sklearn.decomposition.PCA` 这个类的 `n_components` 参数能够接受整数和浮点数作为参数。当为整数是，指明需要选取多少主成分。但为浮点数（0.0~1.0）时，指明需要保存原始数据多少信息。这里传入参数 `n_components=0.95` 即可。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(48000, 187)"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.pipeline import Pipeline\n",
    "from sklearn.decomposition import PCA \n",
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "\n",
    "pipeline = Pipeline([\n",
    "    ('pca', PCA(n_components=0.95)),\n",
    "    ('scaler', StandardScaler())\n",
    "    \n",
    "])\n",
    "\n",
    "X_train_processed = pipeline.fit_transform(X_train)\n",
    "X_val_processed = pipeline.transform(X_val)\n",
    "\n",
    "X_train_processed.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 构建分类器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "SGDClassifier(alpha=0.0001, average=False, class_weight=None,\n",
       "              early_stopping=False, epsilon=0.1, eta0=0.0, fit_intercept=True,\n",
       "              l1_ratio=0.15, learning_rate='optimal', loss='hinge',\n",
       "              max_iter=200, n_iter_no_change=5, n_jobs=4, penalty='l2',\n",
       "              power_t=0.5, random_state=None, shuffle=True, tol=0.001,\n",
       "              validation_fraction=0.1, verbose=0, warm_start=False)"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.linear_model import SGDClassifier\n",
    "\n",
    "sgd_clf = SGDClassifier(max_iter=200, tol=1e-3, n_jobs=4)\n",
    "\n",
    "sgd_clf.fit(X_train_processed, y_train)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 观察结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_val_processed = pipeline.transform(X_val)\n",
    "\n",
    "y_val_predict = sgd_clf.predict(X_val_processed)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>f1-score</th>\n",
       "      <th>precision</th>\n",
       "      <th>recall</th>\n",
       "      <th>support</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>T恤</th>\n",
       "      <td>0.789835</td>\n",
       "      <td>0.741667</td>\n",
       "      <td>0.844694</td>\n",
       "      <td>1159.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>裤子</th>\n",
       "      <td>0.962933</td>\n",
       "      <td>0.978477</td>\n",
       "      <td>0.947875</td>\n",
       "      <td>1247.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>套衫</th>\n",
       "      <td>0.737435</td>\n",
       "      <td>0.717527</td>\n",
       "      <td>0.758478</td>\n",
       "      <td>1209.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>裙子</th>\n",
       "      <td>0.852146</td>\n",
       "      <td>0.840784</td>\n",
       "      <td>0.863820</td>\n",
       "      <td>1241.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>外套</th>\n",
       "      <td>0.733635</td>\n",
       "      <td>0.701575</td>\n",
       "      <td>0.768766</td>\n",
       "      <td>1159.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>凉鞋</th>\n",
       "      <td>0.926037</td>\n",
       "      <td>0.932014</td>\n",
       "      <td>0.920136</td>\n",
       "      <td>1177.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>汗衫</th>\n",
       "      <td>0.574359</td>\n",
       "      <td>0.671024</td>\n",
       "      <td>0.502037</td>\n",
       "      <td>1227.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>运动鞋</th>\n",
       "      <td>0.914286</td>\n",
       "      <td>0.922271</td>\n",
       "      <td>0.906438</td>\n",
       "      <td>1165.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>包</th>\n",
       "      <td>0.941558</td>\n",
       "      <td>0.931727</td>\n",
       "      <td>0.951600</td>\n",
       "      <td>1219.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>踝靴</th>\n",
       "      <td>0.936869</td>\n",
       "      <td>0.944020</td>\n",
       "      <td>0.929825</td>\n",
       "      <td>1197.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>accuracy</th>\n",
       "      <td>0.839083</td>\n",
       "      <td>0.839083</td>\n",
       "      <td>0.839083</td>\n",
       "      <td>0.839083</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>macro avg</th>\n",
       "      <td>0.836909</td>\n",
       "      <td>0.838109</td>\n",
       "      <td>0.839367</td>\n",
       "      <td>12000.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>weighted avg</th>\n",
       "      <td>0.837047</td>\n",
       "      <td>0.838693</td>\n",
       "      <td>0.839083</td>\n",
       "      <td>12000.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              f1-score  precision    recall       support\n",
       "T恤            0.789835   0.741667  0.844694   1159.000000\n",
       "裤子            0.962933   0.978477  0.947875   1247.000000\n",
       "套衫            0.737435   0.717527  0.758478   1209.000000\n",
       "裙子            0.852146   0.840784  0.863820   1241.000000\n",
       "外套            0.733635   0.701575  0.768766   1159.000000\n",
       "凉鞋            0.926037   0.932014  0.920136   1177.000000\n",
       "汗衫            0.574359   0.671024  0.502037   1227.000000\n",
       "运动鞋           0.914286   0.922271  0.906438   1165.000000\n",
       "包             0.941558   0.931727  0.951600   1219.000000\n",
       "踝靴            0.936869   0.944020  0.929825   1197.000000\n",
       "accuracy      0.839083   0.839083  0.839083      0.839083\n",
       "macro avg     0.836909   0.838109  0.839367  12000.000000\n",
       "weighted avg  0.837047   0.838693  0.839083  12000.000000"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import classification_report\n",
    "\n",
    "categories_name = ['T恤','裤子','套衫','裙子','外套','凉鞋','汗衫','运动鞋','包','踝靴']\n",
    "\n",
    "pd.DataFrame(classification_report(y_val, y_val_predict, output_dict=True, target_names=categories_name)).transpose()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>T恤</th>\n",
       "      <th>裤子</th>\n",
       "      <th>套衫</th>\n",
       "      <th>裙子</th>\n",
       "      <th>外套</th>\n",
       "      <th>凉鞋</th>\n",
       "      <th>汗衫</th>\n",
       "      <th>运动鞋</th>\n",
       "      <th>包</th>\n",
       "      <th>踝靴</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>T恤</th>\n",
       "      <td>979</td>\n",
       "      <td>4</td>\n",
       "      <td>26</td>\n",
       "      <td>59</td>\n",
       "      <td>8</td>\n",
       "      <td>0</td>\n",
       "      <td>75</td>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>裤子</th>\n",
       "      <td>13</td>\n",
       "      <td>1182</td>\n",
       "      <td>14</td>\n",
       "      <td>26</td>\n",
       "      <td>6</td>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>套衫</th>\n",
       "      <td>25</td>\n",
       "      <td>2</td>\n",
       "      <td>917</td>\n",
       "      <td>10</td>\n",
       "      <td>165</td>\n",
       "      <td>0</td>\n",
       "      <td>78</td>\n",
       "      <td>0</td>\n",
       "      <td>12</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>裙子</th>\n",
       "      <td>60</td>\n",
       "      <td>13</td>\n",
       "      <td>17</td>\n",
       "      <td>1072</td>\n",
       "      <td>51</td>\n",
       "      <td>0</td>\n",
       "      <td>24</td>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>外套</th>\n",
       "      <td>6</td>\n",
       "      <td>1</td>\n",
       "      <td>111</td>\n",
       "      <td>42</td>\n",
       "      <td>891</td>\n",
       "      <td>0</td>\n",
       "      <td>92</td>\n",
       "      <td>0</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>凉鞋</th>\n",
       "      <td>4</td>\n",
       "      <td>1</td>\n",
       "      <td>6</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1083</td>\n",
       "      <td>4</td>\n",
       "      <td>46</td>\n",
       "      <td>16</td>\n",
       "      <td>16</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>汗衫</th>\n",
       "      <td>221</td>\n",
       "      <td>4</td>\n",
       "      <td>176</td>\n",
       "      <td>48</td>\n",
       "      <td>143</td>\n",
       "      <td>0</td>\n",
       "      <td>616</td>\n",
       "      <td>0</td>\n",
       "      <td>19</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>运动鞋</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>55</td>\n",
       "      <td>0</td>\n",
       "      <td>1056</td>\n",
       "      <td>6</td>\n",
       "      <td>48</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>包</th>\n",
       "      <td>7</td>\n",
       "      <td>1</td>\n",
       "      <td>9</td>\n",
       "      <td>17</td>\n",
       "      <td>6</td>\n",
       "      <td>3</td>\n",
       "      <td>14</td>\n",
       "      <td>2</td>\n",
       "      <td>1160</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>踝靴</th>\n",
       "      <td>5</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>21</td>\n",
       "      <td>12</td>\n",
       "      <td>40</td>\n",
       "      <td>4</td>\n",
       "      <td>1113</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      T恤    裤子   套衫    裙子   外套    凉鞋   汗衫   运动鞋     包    踝靴\n",
       "T恤   979     4   26    59    8     0   75     0     8     0\n",
       "裤子    13  1182   14    26    6     0    3     0     2     1\n",
       "套衫    25     2  917    10  165     0   78     0    12     0\n",
       "裙子    60    13   17  1072   51     0   24     1     3     0\n",
       "外套     6     1  111    42  891     0   92     0    15     1\n",
       "凉鞋     4     1    6     1    0  1083    4    46    16    16\n",
       "汗衫   221     4  176    48  143     0  616     0    19     0\n",
       "运动鞋    0     0    0     0    0    55    0  1056     6    48\n",
       "包      7     1    9    17    6     3   14     2  1160     0\n",
       "踝靴     5     0    2     0    0    21   12    40     4  1113"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import confusion_matrix\n",
    "\n",
    "con_mat = confusion_matrix(y_val, y_val_predict)\n",
    "\n",
    "pd.DataFrame(con_mat, index=categories_name, columns=categories_name)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 使用卷积神经网络"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [],
   "source": [
    "def build_model():\n",
    "    model = keras.Sequential([\n",
    "        keras.layers.Reshape((28, 28, 1), input_shape=[28 * 28]),\n",
    "        keras.layers.Conv2D(32, (5, 5), activation='relu', padding='same'),\n",
    "        keras.layers.Conv2D(32, (5, 5), activation='relu', padding='same'),\n",
    "        keras.layers.MaxPool2D(pool_size=(2, 2)),\n",
    "        keras.layers.Dropout(rate=0.25),\n",
    "        \n",
    "        keras.layers.Conv2D(64, (3, 3), activation='relu', padding='same'),\n",
    "        keras.layers.Conv2D(64, (3, 3), activation='relu', padding='same'),\n",
    "        keras.layers.MaxPool2D(pool_size=(2, 2), strides=(2,2)),\n",
    "        keras.layers.Dropout(rate=0.25),\n",
    "        \n",
    "        keras.layers.Flatten(),\n",
    "        keras.layers.Dense(512, activation='relu'),\n",
    "        keras.layers.BatchNormalization(),\n",
    "        keras.layers.Dropout(rate=0.5),\n",
    "        keras.layers.Dense(10, activation='softmax')\n",
    "    ])\n",
    "    \n",
    "    model.compile(loss='sparse_categorical_crossentropy',\n",
    "                  optimizer=keras.optimizers.Adam(lr=0.003),\n",
    "                  metrics=['acc'])\n",
    "    return model\n",
    "\n",
    "model = build_model()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 48000 samples, validate on 12000 samples\n",
      "Epoch 1/40\n",
      "48000/48000 [==============================] - 12s 243us/sample - loss: 0.6284 - acc: 0.7761 - val_loss: 0.3972 - val_acc: 0.8486\n",
      "Epoch 2/40\n",
      "48000/48000 [==============================] - 11s 228us/sample - loss: 0.4220 - acc: 0.8486 - val_loss: 0.3005 - val_acc: 0.8895\n",
      "Epoch 3/40\n",
      "48000/48000 [==============================] - 11s 222us/sample - loss: 0.3792 - acc: 0.8620 - val_loss: 0.3474 - val_acc: 0.8702\n",
      "Epoch 4/40\n",
      "48000/48000 [==============================] - 11s 225us/sample - loss: 0.3465 - acc: 0.8743 - val_loss: 0.2605 - val_acc: 0.9021\n",
      "Epoch 5/40\n",
      "48000/48000 [==============================] - 11s 237us/sample - loss: 0.3055 - acc: 0.8889 - val_loss: 0.2534 - val_acc: 0.9069\n",
      "Epoch 6/40\n",
      "48000/48000 [==============================] - 11s 228us/sample - loss: 0.3215 - acc: 0.8843 - val_loss: 0.2484 - val_acc: 0.9062\n",
      "Epoch 7/40\n",
      "48000/48000 [==============================] - 11s 224us/sample - loss: 0.2852 - acc: 0.8978 - val_loss: 0.2215 - val_acc: 0.9169\n",
      "Epoch 8/40\n",
      "48000/48000 [==============================] - 11s 225us/sample - loss: 0.2711 - acc: 0.9026 - val_loss: 0.2197 - val_acc: 0.9172\n",
      "Epoch 9/40\n",
      "48000/48000 [==============================] - 11s 230us/sample - loss: 0.2626 - acc: 0.9044 - val_loss: 0.2191 - val_acc: 0.9233\n",
      "Epoch 10/40\n",
      "48000/48000 [==============================] - 11s 235us/sample - loss: 0.2567 - acc: 0.9071 - val_loss: 0.2087 - val_acc: 0.9212\n",
      "Epoch 11/40\n",
      "48000/48000 [==============================] - 11s 232us/sample - loss: 0.2407 - acc: 0.9128 - val_loss: 0.2051 - val_acc: 0.9226\n",
      "Epoch 12/40\n",
      "48000/48000 [==============================] - 11s 229us/sample - loss: 0.2340 - acc: 0.9146 - val_loss: 0.2112 - val_acc: 0.9203\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<tensorflow.python.keras.callbacks.History at 0x7f875cc4fb00>"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train_cnn = X_train / 255.0\n",
    "X_val_cnn = X_val / 255.0\n",
    "\n",
    "callbacks = [\n",
    "    keras.callbacks.EarlyStopping(patience=3, monitor=\"val_acc\")\n",
    "]\n",
    "model.fit(X_train_cnn, y_train, epochs=40, batch_size=32, validation_data=(X_val_cnn, y_val), callbacks=callbacks)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>T恤</th>\n",
       "      <th>裤子</th>\n",
       "      <th>套衫</th>\n",
       "      <th>裙子</th>\n",
       "      <th>外套</th>\n",
       "      <th>凉鞋</th>\n",
       "      <th>汗衫</th>\n",
       "      <th>运动鞋</th>\n",
       "      <th>包</th>\n",
       "      <th>踝靴</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>T恤</th>\n",
       "      <td>1076</td>\n",
       "      <td>0</td>\n",
       "      <td>26</td>\n",
       "      <td>17</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>37</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>裤子</th>\n",
       "      <td>1</td>\n",
       "      <td>1228</td>\n",
       "      <td>1</td>\n",
       "      <td>15</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>套衫</th>\n",
       "      <td>15</td>\n",
       "      <td>0</td>\n",
       "      <td>1137</td>\n",
       "      <td>11</td>\n",
       "      <td>26</td>\n",
       "      <td>0</td>\n",
       "      <td>20</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>裙子</th>\n",
       "      <td>33</td>\n",
       "      <td>2</td>\n",
       "      <td>9</td>\n",
       "      <td>1165</td>\n",
       "      <td>21</td>\n",
       "      <td>0</td>\n",
       "      <td>11</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>外套</th>\n",
       "      <td>2</td>\n",
       "      <td>3</td>\n",
       "      <td>88</td>\n",
       "      <td>40</td>\n",
       "      <td>973</td>\n",
       "      <td>0</td>\n",
       "      <td>53</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>凉鞋</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1154</td>\n",
       "      <td>0</td>\n",
       "      <td>16</td>\n",
       "      <td>1</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>汗衫</th>\n",
       "      <td>180</td>\n",
       "      <td>0</td>\n",
       "      <td>119</td>\n",
       "      <td>35</td>\n",
       "      <td>55</td>\n",
       "      <td>0</td>\n",
       "      <td>834</td>\n",
       "      <td>0</td>\n",
       "      <td>4</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>运动鞋</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>0</td>\n",
       "      <td>1145</td>\n",
       "      <td>0</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>包</th>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>7</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1207</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>踝靴</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>6</td>\n",
       "      <td>0</td>\n",
       "      <td>47</td>\n",
       "      <td>1</td>\n",
       "      <td>1143</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       T恤    裤子    套衫    裙子   外套    凉鞋   汗衫   运动鞋     包    踝靴\n",
       "T恤   1076     0    26    17    1     0   37     0     2     0\n",
       "裤子      1  1228     1    15    0     0    1     0     1     0\n",
       "套衫     15     0  1137    11   26     0   20     0     0     0\n",
       "裙子     33     2     9  1165   21     0   11     0     0     0\n",
       "外套      2     3    88    40  973     0   53     0     0     0\n",
       "凉鞋      0     0     0     0    0  1154    0    16     1     6\n",
       "汗衫    180     0   119    35   55     0  834     0     4     0\n",
       "运动鞋     0     0     0     0    0     3    0  1145     0    17\n",
       "包       2     0     7     2    1     0    0     0  1207     0\n",
       "踝靴      0     0     0     0    0     6    0    47     1  1143"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_val_predict = model.predict_classes(X_val_cnn)\n",
    "\n",
    "con_mat = confusion_matrix(y_val, y_val_predict)\n",
    "\n",
    "pd.DataFrame(con_mat, index=categories_name, columns=categories_name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>f1-score</th>\n",
       "      <th>precision</th>\n",
       "      <th>recall</th>\n",
       "      <th>support</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>T恤</th>\n",
       "      <td>0.871961</td>\n",
       "      <td>0.822002</td>\n",
       "      <td>0.928387</td>\n",
       "      <td>1159.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>裤子</th>\n",
       "      <td>0.990323</td>\n",
       "      <td>0.995945</td>\n",
       "      <td>0.984763</td>\n",
       "      <td>1247.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>套衫</th>\n",
       "      <td>0.875963</td>\n",
       "      <td>0.819755</td>\n",
       "      <td>0.940447</td>\n",
       "      <td>1209.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>裙子</th>\n",
       "      <td>0.922407</td>\n",
       "      <td>0.906615</td>\n",
       "      <td>0.938759</td>\n",
       "      <td>1241.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>外套</th>\n",
       "      <td>0.870304</td>\n",
       "      <td>0.903435</td>\n",
       "      <td>0.839517</td>\n",
       "      <td>1159.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>凉鞋</th>\n",
       "      <td>0.986325</td>\n",
       "      <td>0.992261</td>\n",
       "      <td>0.980459</td>\n",
       "      <td>1177.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>汗衫</th>\n",
       "      <td>0.764086</td>\n",
       "      <td>0.872385</td>\n",
       "      <td>0.679707</td>\n",
       "      <td>1227.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>运动鞋</th>\n",
       "      <td>0.965023</td>\n",
       "      <td>0.947848</td>\n",
       "      <td>0.982833</td>\n",
       "      <td>1165.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>包</th>\n",
       "      <td>0.991376</td>\n",
       "      <td>0.992599</td>\n",
       "      <td>0.990156</td>\n",
       "      <td>1219.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>踝靴</th>\n",
       "      <td>0.967414</td>\n",
       "      <td>0.980274</td>\n",
       "      <td>0.954887</td>\n",
       "      <td>1197.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>accuracy</th>\n",
       "      <td>0.921833</td>\n",
       "      <td>0.921833</td>\n",
       "      <td>0.921833</td>\n",
       "      <td>0.921833</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>macro avg</th>\n",
       "      <td>0.920518</td>\n",
       "      <td>0.923312</td>\n",
       "      <td>0.921991</td>\n",
       "      <td>12000.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>weighted avg</th>\n",
       "      <td>0.920595</td>\n",
       "      <td>0.923653</td>\n",
       "      <td>0.921833</td>\n",
       "      <td>12000.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              f1-score  precision    recall       support\n",
       "T恤            0.871961   0.822002  0.928387   1159.000000\n",
       "裤子            0.990323   0.995945  0.984763   1247.000000\n",
       "套衫            0.875963   0.819755  0.940447   1209.000000\n",
       "裙子            0.922407   0.906615  0.938759   1241.000000\n",
       "外套            0.870304   0.903435  0.839517   1159.000000\n",
       "凉鞋            0.986325   0.992261  0.980459   1177.000000\n",
       "汗衫            0.764086   0.872385  0.679707   1227.000000\n",
       "运动鞋           0.965023   0.947848  0.982833   1165.000000\n",
       "包             0.991376   0.992599  0.990156   1219.000000\n",
       "踝靴            0.967414   0.980274  0.954887   1197.000000\n",
       "accuracy      0.921833   0.921833  0.921833      0.921833\n",
       "macro avg     0.920518   0.923312  0.921991  12000.000000\n",
       "weighted avg  0.920595   0.923653  0.921833  12000.000000"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.DataFrame(classification_report(y_val, y_val_predict, output_dict=True, target_names=categories_name)).transpose()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 总结\n",
    "\n",
    "对比神经网络，这些需要手动选取特征的方法，显得缺少竞争力。尤其是对于图像分类的任务，卷积神经网络能够更加高效地提取到图像中的特征，得到效果更好的模型。另外还能利用以及训练好的模型中的卷积层部分来完成特征提取，这对于训练数据较少的场景很有帮助。\n",
    "\n",
    "虽然，神经网络在近些年大放异彩，但是深入掌握传统机器学习中的经典方法，对于深刻理解各类机器学习算法很有帮助。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
